<?php
namespace app\service;

use think\Db;
use think\Log;
use app\api\model\ChatLists;
use app\api\model\User;
use app\api\model\UserData;
use app\api\model\GradeNoble;
use app\api\model\Task;
use app\api\model\ShenheTask;
use app\service\TrtcService;
use GatewayClient\Gateway;

class CheckLianmai
{
    public static function CheckLianmai($orderid)
    {
        $close = false;
        $time = time();
        $hangupReason = '';
        echo $time . " | start | 检查连麦状态 | 订单ID：" . $orderid . "\n";
        // 聊天表检查状态
       // $chat = Db::name('privatechat')->master()->where(['type'=>['in', [9,10]],'order_id'=>$orderid])->find();
        $chat = Db::name('privatechat')->master()->where(['order_id'=>$orderid])->find();
        $order = Db::name('order_common')->master()->where(['types'=>2,'id'=>$orderid])->find();
        // $chat_over_dec_not = Db::name('config_system')->master()->where(['title'=>'chat_over_dec_not'])->value('content');
        if(!$chat){
            Log::write('lianmai_error-'.$orderid.'-10001', 'error');
            return false;
        }
        $orderdata = json_decode($order['data'], true);

        // 避免因延迟问题（扣费执行后发起redis写入期间用户挂断电话，导致后续redis还是写入了依旧执行扣费）
        if(isset($orderdata['end'])){
            return false;
        }

        $lianstatus = true;
        if (false) {
        if(isset($orderdata['checksocket']) && $orderdata['checksocket']==2){
            try {
                $redis = new \Redis();
                $redis->connect('127.0.0.1',6379);
                if(getenv('REDIS_PASS')){
                    $redis->auth(getenv('REDIS_PASS'));
                }
                $userorder = $redis->get('zaima:lianmaiuser:'.$order['user_id']);
                $touserorder = $redis->get('zaima:lianmaiuser:'.$orderdata['another_id']);

                $lianmaiuserlast_user_key = 'zaima:lianmaiuserlast:'.$orderid.':'.$order['user_id'];
                $lianmaiuserlast_touser_key = 'zaima:lianmaiuserlast:'.$orderid.':'.$orderdata['another_id'];
                if (!$userorder) {
                    $socketClose = $redis->get($lianmaiuserlast_user_key);
                    if ($socketClose) {
                        $timer = $time - $socketClose;
                        if ($timer > 38) {
                            $close = true;
                        }
                    } else {
                        $close = true;
                    }
                }
                if (!$touserorder) {
                    $socketClose = $redis->get($lianmaiuserlast_touser_key);
                    if ($socketClose) {
                        $timer = $time - $socketClose;
                        if ($timer > 38) {
                            $close = true;
                        }
                    } else {
                        $close = true;
                    }
                }
                $lianstatus = !$close;
                if ($close) {
                if (!$userorder) {
                    echo 'user_id:'.$order['user_id']." socket断开";
                    $hangupReason .= 'uid:'.$order['user_id']."断线";
                }
                if (!$touserorder) {
                    echo 'user_id:'.$orderdata['another_id']." socket断开";
                    $hangupReason .= 'uid:'.$orderdata['another_id']."断线";
                }
                if($userorder && $touserorder && $userorder == $touserorder && $userorder == $orderid){
                    $lianstatus = true;
                } else if ($userorder != $touserorder) {
                    echo $orderid . ":" . $userorder . "!=" . $touserorder ." 续签异常1";
                    $hangupReason .= " ".$orderid . ":" . $order['user_id'] . '[' . $userorder . "]!=".$orderdata['another_id']."[" . $touserorder ."] 续签异常1";
                } else if ($userorder != $orderid) {
                    echo $orderid . ":" . $userorder . "!=" . $touserorder ." 续签异常2";
                    $hangupReason .= " ".$orderid . ":" . $order['user_id'] . '[' . $userorder . "]!=".$orderdata['another_id']."[" . $touserorder ."] 续签异常2";
                }
                }
            } catch (\Exception $e) {
                echo $e->getMessage();
            }
        }else{
            if (!Gateway::isUidOnline(getenv('SOCKET_PREFIX') . $chat['userid'])) {
                $hangupReason .= 'uid:'.$chat['userid']."断线";
            } else if (!Gateway::isUidOnline(getenv('SOCKET_PREFIX') . $chat['touserid'])) {
                $hangupReason .= 'uid:'.$chat['touserid']."断线";
            } else {
                $lianstatus = true;
            }
        }
        }

        // if(!Gateway::isUidOnline(getenv('SOCKET_PREFIX') . $chat['userid']) || !Gateway::isUidOnline(getenv('SOCKET_PREFIX') . $chat['touserid']) || !$lianstatus){
        if(!$lianstatus){
            Log::write('lianmai_error-lianstatus-10005', 'error');
            self::returnRequest($chat['userid'], $chat['touserid'], 'channel'.$chat['userid'], 0, $chat['type'] - 8, $order, $chat, $hangupReason);
            return false;
        }


        // $ChatChargeRecordMap = $chat['userid'] < $chat['touserid'] ? [
        //     'user_id' => $chat['userid'],
        //     'another_id' => $chat['touserid'],
        // ] :  [
        //     'user_id' => $chat['touserid'],
        //     'another_id' => $chat['userid'],
        // ];
        // $ChatChargeRecords = Db::name('chat_charge_records')->master(true)->where($ChatChargeRecordMap)->find();

        // 检查付费用户是否够金额下次扣费
        // if ($ChatChargeRecords && $ChatChargeRecords['payer']) {
            $user = Db::name('user')->master()->where(['id'=>$order['user_id']])->find();
        // } else {
        //     $user = Db::name('user')->master()->where(['id'=>['in', [$chat['userid'], $chat['touserid']]], 'sex'=>'男'])->find();
        // }
        $minute = ceil(($time + 1 - $orderdata['start']) / 60);
        // 应扣
        // $should = $minute * $orderdata['price'];
        // 实扣
        // $actual = $order['money'];
        // 本次需扣
        // $decval = $should - $actual;
        $decval = $orderdata['price'];
        // 通话额外扣除费用
        
        // $hasnotdec = in_array($order['user_id'], explode(',', $chat_over_dec_not));
        // $extra_rate = $user['volley'] >= 200 && !$hasnotdec ? 0.1 : 0;
        $extra_rate = 0;
        $decvalall = $extra_rate * $decval + $decval;
        // 不够则主动断开聊天
        $privatechat_free = 0;
        // if (isset($orderdata['free_time'])) {
        //     $privatechat_free_line = Db::name('privatechat_free')->find($orderdata['free_id']);
        //     $lianmaiMinute = $privatechat_free_line['audio_second'] + $privatechat_free_line['video_second'] > 0 ? ceil(($privatechat_free_line['audio_second'] + $privatechat_free_line['video_second']) / 60) : 0;
        //     $lianmaiMinute += $minute;
        //     $free_over = false;
        //     if ($lianmaiMinute == 0) {
        //         if ($privatechat_free_line['seller_msg'] >= 200) {
        //             $free_over = true;
        //         }
        //     } elseif ($lianmaiMinute <= 10) {
        //         if ($privatechat_free_line['seller_msg'] >= 150) {
        //             $free_over = true;
        //         }
        //     } elseif ($lianmaiMinute <= 20) {
        //         if ($privatechat_free_line['seller_msg'] >= 100) {
        //             $free_over = true;
        //         }
        //     } elseif ($lianmaiMinute <= 30) {
        //         if ($privatechat_free_line['seller_msg'] >= 50) {
        //             $free_over = true;
        //         }
        //     } elseif ($lianmaiMinute < 35) {
        //         if ($privatechat_free_line['seller_msg'] >= 0) {
        //             $free_over = true;
        //         }
        //     } elseif ($lianmaiMinute >= 35) {
        //         $free_over = true;
        //     }
        //     if ($free_over) {
        //         Db::name('privatechat_free')->where(['id'=>$privatechat_free_line['id']])->update(['end_time'=>time()]);
        //     } else {
        //         $privatechat_free = ($orderdata['types'] + 1 == $orderdata['free_method'] || $orderdata['free_method'] == 4) && $orderdata['free_time'] > $time ? 1 : 0;
        //     }
        // }
        if($privatechat_free == 0 && $user['volley'] < $decvalall){
            $hangupReason .= 'uid:'.$user['id']."余额不足";
            self::returnRequest($chat['userid'], $chat['touserid'], 'channel'.$chat['userid'], 0, $chat['type'] - 8, $order, $chat, $hangupReason);
            return false;
        }
        Db::startTrans();
        try {
            $time = time();
            $nexttime = $orderdata['start'] + 60 * ($minute - 1 > 0 ? $minute : 1);
            // $redis->set('lianmai:' . $orderid, $nexttime . ' - ' . $time .' = '. ($nexttime - $time), $nexttime - $time);
            self::createMic($order, $chat, $user, $decval, $extra_rate, $privatechat_free);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            Log::write('lianmai_error-'.$e->getMessage() .'-10002'.$e->getFile().':'.$e->getLine(), 'error');
            $hangupReason .= "扣费失败";
            self::returnRequest($chat['userid'], $chat['touserid'], 'channel'.$chat['userid'], 0, $chat['type'] - 8, $order, $chat, $hangupReason);
            return false;
        }
        // 足够则再次写入redis监听
        // 订阅发布状态下不能写入redis，使用curl请求
        // try {
        //     $redis->set('zaima:lianmai:' . (string)$orderid, (string)($nexttime) . ' - ' . (string)($time) .' = '. (string)($nexttime - $time), $nexttime - $time);
        // } catch (\Exception $e) {
        //     Log::write('lianmai_error-'.$e->getMessage() .'-10003', 'error');
        // }
        try {
            $url = 'http://' . getenv('APP_HOST_LOCAL') . '/api/privatechat/aotuinc';
            curl($url, json_encode(['orderid' => $orderid, 'nexttime' => $nexttime]), 0);
        } catch (\Exception $e) {
            Log::write('lianmai_error-'.$e->getMessage() .'-10004', 'error');
            $hangupReason .= "程序异常";
            self::returnRequest($chat['userid'], $chat['touserid'], 'channel'.$chat['userid'], 0, $chat['type'] - 8, $order, $chat, $hangupReason);
        }



        echo "end\n";
    }


    public static function returnRequest($user_id, $another_id, $channel, $status, $types, $order, $chat, $hangupReason)
    {
        // $user_id = I('user_id');
        // $another_id = I('another_id');
        // $channel = I('channel');        // 加入的频道
        // $status = I('status');          // 0取消 | 1接听 | 2无权限
        // $types = I('types');            // 1语音 | 2视频
        // $orderid = I('orderid');

        $timenow = time();

        $user_privacy = $user = Db::name('user')->master()->where(['id' => $user_id])->find();
        $user_id_privacy = $user_id;
        $touser_id_privacy = $another_id;
        if ($user['reg']==2) {
            $user = Db::name('user')->master()->where(['id' => $user_privacy['authcode']])->find();
            $user_id = $user['id'];
            $another_id = Db::name('user')->master()->where(['id' => $touser_id_privacy])->value('authcode');
        }

        if ($order) {
            $order_data = $data = json_decode($order['data'], true);

            if (isset($data['start'])) {
                $data['end'] = $timenow;
            } else {
                $data['start'] = $timenow;
            }

            $data_json = json_encode($data);

            Db::name('order_common')->where(['id' => $order['id']])->update(['data' => $data_json]);

            if ($chat) {
                $data = json_decode($chat['data'], true);
                if (isset($data['start'])) {
                    // 校对时长
                    $pretime = ($order_data['duration'] > 0 ? $order_data['duration'] : 1) * 60 + $order_data['start'];
                    if ($pretime < $timenow) {
                        $data['end'] = $pretime;
                    }else {
                        $data['end'] = $timenow - $order_data['start'] < 15 ? $order_data['start'] + 10 : $timenow;
                    }
                } else {
                    $data['start'] = $timenow;
                    $data['status'] = $status;
                }
                $data['payer'] = $order['user_id'];
                $data['hpr'] = $hangupReason;
                $data_json = json_encode($data, JSON_UNESCAPED_UNICODE);
                Db::name('privatechat')->where(['id' => $chat['id']])->update(['data' => $data_json]);

                $chat['data'] = $data_json;
                (new \app\service\TencentIM)->modify_c2c_msg($chat['userid'], $chat['touserid'], $data['MsgKey'], json_encode($chat, true));

                if (isset($order_data['free_id']) && ($data['end'] - $data['start']) > 0) {
                    $freeKey = ['audio_second', 'video_second'];
                    Db::name('privatechat_free')->where(['id'=>$order_data['free_id']])->setInc($freeKey[$chat['type'] - 9], $data['end'] - $data['start']);
                }

                $chat['data'] = $data_json;
                (new ChatLists)->changeLists($chat['userid'], $chat['touserid']);

                // 强制移除房间
                try {
                    TrtcService::free($chat['userid']);
                } catch (\Exception $e) {
                    
                }
            }
        }

        Gateway::sendToUid(getenv('SOCKET_PREFIX') . $user_id, json_encode([
            'code' => 200,
            'action' => 'Home/Privatechat/returnRequest',
            'data' => [
                'user_id' => $user_id_privacy,
                'another_id' => $touser_id_privacy,
                'types' => $types,
                'channel' => $channel,
                'name' => $user['name'],
                'status' => $status
            ]
        ]));
        Gateway::sendToUid(getenv('SOCKET_PREFIX') . $another_id, json_encode([
            'code' => 200,
            'action' => 'Home/Privatechat/returnRequest',
            'data' => [
                'user_id' => $touser_id_privacy,
                'another_id' => $user_id_privacy,
                'types' => $types,
                'channel' => $channel,
                'name' => $user['name'],
                'status' => $status
            ]
        ]));

        if (!$status) {
            ChatLists::pushNewMsg($chat);
            // $this->getOtherList(json_encode(['userid' => $another_id, 'count' => '', 'type' => '']));
        }
        echo "通话断开\n";
    }



    // 语音视频扣费
    public static function createMic($order, $chat, $toUser, $decval, $extra_rate, $privatechat_free = 0)
    {
        $User = new User;

        $time = time();

        $data = json_decode($order['data'], true);

        $free_use = 0;  // 是否使用账户免费时间
        $status = 1;

        if ($data['privacy']) {
            $chatUserInfos = Db::name('user')->master()->where(['id'=>['in', [$chat['userid'],$chat['touserid']]]])->column('*', 'id');
            if($toUser['id'] == $chatUserInfos[$chat['userid']]['authcode']){
                $mine = Db::name('user')->master()->find($chatUserInfos[$chat['touserid']]['authcode']);
                $recharge_user_privacy = $chatUserInfos[$chat['userid']];
                $another_user_privacy = $chatUserInfos[$chat['touserid']];
                $chat['userid_real'] = $toUser['id'];
                $chat['touserid_real'] = $mine['id'];
                $mine_privacy = $chatUserInfos[$chat['touserid']];
            }else{
                $mine = Db::name('user')->master()->find($chatUserInfos[$chat['userid']]['authcode']);
                $another_user_privacy = $chatUserInfos[$chat['userid']];
                $recharge_user_privacy = $chatUserInfos[$chat['touserid']];
                $chat['userid_real'] = $mine['id'];
                $chat['touserid_real'] = $toUser['id'];
                $mine_privacy = $chatUserInfos[$chat['userid']];
            }
            $recharge_user = $toUser;
            $another_user = $mine;
        } else {
            if($toUser['id'] == $chat['userid']){
                $mine_privacy = $mine = Db::name('user')->master()->find($chat['touserid']);
            }else{
                $mine_privacy = $mine = Db::name('user')->master()->find($chat['userid']);
            }
        
            $recharge_user_privacy = $recharge_user = $toUser;
            $another_user_privacy = $another_user = $mine;
            $chat['userid_real'] = $chat['userid'];
            $chat['touserid_real'] = $chat['touserid'];
        }

        try {
            $userRepeatCheck = Db::name('user_repeat_check')->where(['user_id'=>['in', [$chat['userid_real'], $chat['touserid_real']]]])->column('user_id');
            if (sizeof($userRepeatCheck)) {
                $userChannelProfiles = Db::name('user_channel_profile')->alias('p')->join('user_repeat_check c', 'c.user_id=p.user_id and c.sys_channel=p.sys_channel')->where(['p.user_id'=>['in', $userRepeatCheck]])->column('p.user_id,p.sex,p.name', 'p.user_id');
                foreach ($userChannelProfiles as $ucpkey => $ucpvalue) {
                    if ($ucpkey == $recharge_user_privacy['id']) {
                        $recharge_user_privacy['name'] = $ucpvalue['name'];
                    }
                    if ($ucpkey == $another_user_privacy['id']) {
                        $another_user_privacy['name'] = $ucpvalue['name'];
                    }
                    if ($ucpkey == $mine_privacy['id']) {
                        $mine_privacy['name'] = $ucpvalue['name'];
                    }
                }
            }
        } catch (\Exception $e) {
            
        }
    

        if ($recharge_user['noble_time'] > $time && $recharge_user['noble_grade']) {
            $gradeNoble = GradeNoble::get(['grade' => $recharge_user['noble_grade']]);

            if ($gradeNoble) {
                $privilege = explode(',',$gradeNoble['privilege']);

                if ($data['types'] == 1) {
                    $privilege_field = 11;
                    $privilegeValue_field = 1;
                } else {
                    $privilege_field = 12;
                    $privilegeValue_field = 2;
                }

                if (in_array($privilege_field, $privilege)) {
                    $privilegeValue = explode(',',$gradeNoble['value']);

                    if (isset($privilegeValue[$privilegeValue_field]) && $privilegeValue[$privilegeValue_field]) {
                        $userCount = Db::name('grade_noble_use')->where(['types' => $privilegeValue_field + 1, 'user_id' => $recharge_user['id'], 'create_time' => ['egt', strtotime(date('Ymd'))]])->count();

                        if ($privilegeValue[$privilegeValue_field] > $userCount) {
                            Db::name('grade_noble_use')->insert(['types' => $privilegeValue_field + 1, 'user_id' => $recharge_user['id'], 'create_time' => $time]);

                            $status = 0;
                        }
                    }
                }
            }
        }

        $start_time = $time;


        if ($data['duration']) {
            $price = $add = $decval;
            $score = $decval;


            if(isset($data['start'])){
                $start_time = $data['start'];
                $realminute = ceil(($time - $data['start']) / 60);
                if($realminute > $data['duration']){
                    $data['duration'] = $realminute - 1;
                }
            }
        } else {
            $price = $add = $order['money'];
            $score = $data['score'];

            // 任务
            $task = $chat['type'] == 9 ? 'voice_chat' : 'video_chat';
            Task::finish($task, $chat['userid_real']);
        }



        if ($status) {
            $free_time_field = $chat['type'] == 9 ? 'free_voice' : 'free_video';

            if ($recharge_user[$free_time_field] > 0) {
                Db::name('user')->where(['id' => $recharge_user['id']])->setDec($free_time_field);
                $free_use = 1;
            } else {
                $chatRecords = Db::name('chat_records')->where(['user_id' => $recharge_user['id'], 'data' => '{"orderid":"'.$order['id'].'"}'])->find();
                if ($chatRecords) {
                    $price = 0;

                    if (!$chatRecords['status']) {
                        Db::name('chat_records')->where(['id' => $chatRecords['id']])->setField('status', 1);
                    }
                }
            }
        }
        
        $add_money = $privatechat_free || $free_use || !$status ? 0 : $add;
        
        $add_money = $data['duration'] ? $add_money : 0;
        $data['money'] = $data['duration'] ? $data['money'] + $add : $data['money'];
        $data['score'] = $data['duration'] ? $data['score'] + $score : $data['score'];

        $data['duration'] += 1;

        
        Db::name('order_common')->where(['id' => $order['id']])->update([
            'money' => $order['money'] + $add_money,
            'status' => 1,
            'data' => json_encode($data),
            'update_time' => $time
        ]);

        $msg = trim($chat['content'], '[]');

        $toUserInfo = $toUser;
    
        if ($recharge_user['id'] == $chat['userid_real']) {
            $recharge_msg = '向 ' . $another_user_privacy['name'] . '(' . $chat['touserid'] . ') 发起' . $msg . '付费。分钟数:' . $data['duration'];
        } else {
            $recharge_msg = $mine_privacy['name'] . '(' . $mine_privacy['id'] . ') 发起' . $msg . '付费。分钟数:' . $data['duration'];
        }




        //$desc = Db::name('volley_desc')->where(['content' => $recharge_msg])->find();
        $desc = Db::name('volley_desc')->master()->where(['order_id' => $order['id']])->find();

        $volley_price = $privatechat_free || $free_use || !$status ? 0 : $add;

        $balance = $User->master()->where(['id' => $recharge_user['id']])->value('volley');
        $current_balance = $balance - $volley_price - $volley_price * $extra_rate;
        if ($desc) {
            Db::name('volley_desc')->where(['id' => $desc['id']])->update([
                'price' => $desc['price'] + $volley_price,
                'balance' => $current_balance,
                'content' => $recharge_msg,
            ]);
        } else {
            Db::name('volley_desc')->insert([
                'user_id' => $recharge_user['id'],
                'content' => $recharge_msg,
                'price' => $volley_price,
                'balance' => $current_balance,
                'order_id' => $order['id'],
                'time' => $time
            ]);
        }
        // 用户消费统计
        UserData::createData($recharge_user['id'], $volley_price, 'consume');
    
        $chat_score = $volley_price;
        
        Db::name('privatechat')->where(['id' => $chat['id']])->update([
            'second' => $chat['second'] + 1,
            'money' => $chat['money'] + $volley_price,
            'score' => $chat['score'] + $chat_score
        ]);

        $chat['second'] += 1;
        $chat['money'] += $volley_price;
        $chat['score'] += $chat_score;
        (new \app\service\TencentIM)->modify_c2c_msg($chat['userid'], $chat['touserid'], json_decode($chat['data'], true)['MsgKey'], json_encode($chat, true));

        if (($volley_price + 0) && (!$free_use || $status)) {
            Db::name('user')->where(['id' => $recharge_user['id']])->setDec('volley', ($volley_price + $volley_price * $extra_rate));
        }

        $channel_type = $chat['type'] == 9 ? 'liveaudio' : 'livevideo';
        
        if ($recharge_user['id'] == $chat['userid_real']) {
            User::changeIntimate($chat['userid_real'], $chat['touserid_real'], $price, '接听 ' . $recharge_user_privacy['name'] . '(' . $recharge_user_privacy['id'] . ') 的' . $msg, $order['id'],1,1,$channel_type,$chat_score);
        } else {
            User::changeIntimate($chat['touserid_real'], $chat['userid_real'], $price, '向' . $recharge_user_privacy['name'] . '(' . $recharge_user_privacy['id'] . ') 发起' . $msg, $order['id'],1,1,$channel_type,$chat_score);
        }

        // if($data['duration'] == 1 && $msg == '视频通话'){
        //     ShenheTask::CreateTask($mine['id'],$order['id']);
        // }

    }

}
